package com.inspur.edp.ai.flow.evaluator;

import com.inspur.edp.ai.flow.exception.FlowException;
import com.inspur.edp.ai.flow.metadata.AbsNode;
import com.inspur.edp.ai.flow.metadata.Parameter;
import com.inspur.edp.common.expr.ExpressDSLGeneratorMgr;
import com.inspur.edp.common.expr.ast.ASTContext;
import com.inspur.edp.common.expr.ast.CompileUnitParser;
import com.inspur.edp.common.expr.ast.DefaultASTContext;
import com.inspur.edp.common.expr.evaluator.EvaluatorService;
import com.inspur.edp.common.expr.evaluator.ExpressEvaluator;
import com.inspur.edp.common.expr.parser.ASTParser;
import com.inspur.edp.common.expr.parser.ExpressAstParser;
import com.inspur.edp.common.type.TypeRefer;
import org.apache.commons.lang3.StringUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lizhaorui
 * @date 2025/10/1
 * @description
 */

public class StrCatEvaluatorService {

    private final static String VAR_START_SYMBOL = "{{";
    private final static String VAR_END_SYMBOL = "}}";


    public static StrCatEvaluator build(ASTContext astContext, AbsNode node, String concatContent) {
        List<Parameter> parameters = node.getInputParams();
        Map<String, TypeRefer> inputParamTypeMap = new HashMap<>();
        DefaultASTContext defaultASTContext = (DefaultASTContext) astContext;
        Collection<String> allImports = defaultASTContext.getAllImports();
        if (parameters != null) {
            for (Parameter parameter : parameters) {
                String dsl = ExpressDSLGeneratorMgr.generateDsl(astContext, parameter.getValueExpr());
                CompileUnitParser.ExpressContext expressContext = ASTParser.parse(dsl).express();
                TypeRefer paramType = ExpressAstParser.getOriginalType(expressContext, astContext);
                inputParamTypeMap.put(parameter.getCode(), paramType);
            }
        }
        defaultASTContext.setAllImports(allImports);
        return build(inputParamTypeMap, concatContent);
    }

    public static StrCatEvaluator build(Map<String, TypeRefer> inputParamTypeMap, String concatContent) {
        ASTContext astContext = new DefaultASTContext();
        if (inputParamTypeMap != null) {
            for (Map.Entry<String, TypeRefer> entry : inputParamTypeMap.entrySet()) {
                astContext.addVariable(entry.getKey(), entry.getValue());
            }
        }
        DefaultStrCatEvaluator concatEvaluator = new DefaultStrCatEvaluator();
        build(astContext, concatContent, concatEvaluator);
        return concatEvaluator;
    }

    private static void build(ASTContext astContext, String promptString, DefaultStrCatEvaluator concatEvaluator) {
        int findPosition = promptString.indexOf(VAR_START_SYMBOL);
        if (findPosition >= 0) {
            //第一段
            String firstText = promptString.substring(0, findPosition);
            if (!StringUtils.isEmpty(firstText)) {
                concatEvaluator.addStringSegment(firstText);
            }
            int endPosition = promptString.indexOf(VAR_END_SYMBOL, findPosition);
            if (endPosition > 0) {
                //第二段
                String secondSegmentExpr = promptString.substring(findPosition + 2, endPosition);
                if (!StringUtils.isEmpty(secondSegmentExpr)) {
                    ExpressEvaluator evaluator = EvaluatorService.build(astContext, secondSegmentExpr);
                    concatEvaluator.addExpressSegment(evaluator);
                }
                //第三段
                String thirdSegment = promptString.substring(endPosition + 2);
                build(astContext, thirdSegment, concatEvaluator);
            } else {
                throw new FlowException("variable symbol '{{' and '}}' is not a pair ");
            }
        } else {
            if (!StringUtils.isEmpty(promptString)) {
                concatEvaluator.addStringSegment(promptString);
            }
        }
    }

}